package com.lancoo.ccas53.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lancoo.ccas53.config.LancooConfig;
import com.lancoo.ccas53.entity.CssStudentRange;
import com.lancoo.ccas53.entity.Student;
import com.lancoo.ccas53.entity.TaskInfo;
import com.lancoo.ccas53.entity.TeachingClass;
import com.lancoo.ccas53.exception.BizException;
import com.lancoo.ccas53.pojo.constant.CommonConstants;
import com.lancoo.ccas53.pojo.constant.GlobalConstant;
import com.lancoo.ccas53.pojo.response.BasicPlatformResponse;
import com.lancoo.ccas53.pojo.response.DigitizationResponse;
import com.lancoo.ccas53.pojo.response.LogoutResponse;
import com.lancoo.ccas53.pojo.response.Scheme;
import com.lancoo.ccas53.pojo.response.basicPlatform.*;
import com.lancoo.ccas53.pojo.response.digitization.BuildingInfo;
import com.lancoo.ccas53.pojo.response.digitization.Buildings;
import com.lancoo.ccas53.pojo.response.request.*;
import com.lancoo.ccas53.pojo.response.score.Retake;
import com.lancoo.ccas53.pojo.vo.MsgCoursePlanExamine;
import com.lancoo.ccas53.pojo.vo.MsgTimeAdjustment;
import com.lancoo.ccas53.service.*;
import com.lancoo.ccas53.util.MD5Util;
import com.lancoo.ccas53.util.ResponseObject;
import com.lancoo.ccas53.util.SplitTeacherTeachingClass;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpStatus;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @ClassName YunBasicServiceImpl
 * @Description 基础平台的服务实现类
 * @Author quin
 * @Date 2024/5/20 19:34
 */
@Slf4j
@Service
public class YunBasicServiceImpl implements YunBasicService, Serializable {
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private LancooConfig lancooConfig;
    @Resource
    private TeachingClassService teachingClassService;
    @Resource
    private ScheduleService scheduleService;
    @Resource
    private StudentRetakeService studentRetakeService;
    @Resource
    private TaskInfoService taskInfoService;
    @Resource
    private StudentService studentService;
    @Resource
    private CssStudentRangeService cssStudentRangeService;

    @Override
    public SubSystemsMainServer getSubSystemsMainServer(String sysIDs, Boolean isInner) {
        //获取子系统的服务器地址信息  http://192.168.129.1:8033/showdoc/web/#/6?page_id=1249
        String m_strSubSystemUrl = "/BaseApi/Global/GetSubSystemsMainServerBySubjectID";
        //获取子系统的内网服务器地址信息  http://192.168.129.1:8033/showdoc/web/#/6?page_id=1251
        String m_strSubInnerSystemUrl = "/BaseApi/Global/GetSubSystemsInnerServerBySubjectID";
        SubSystemsMainServer subSystemsMainServer = new SubSystemsMainServer();
        if (StrUtil.isBlank(sysIDs)) {
            subSystemsMainServer.setWsSvrAddr(lancooConfig.getBaseAddr());
            subSystemsMainServer.setWebSvrAddr(lancooConfig.getBaseAddr());
            return subSystemsMainServer;
        }

        HashMap hashMap = new HashMap();
        hashMap.put("sysIDs", sysIDs);
        hashMap.put("period", lancooConfig.getPeriod());
        //判断调用的是内网还是外网接口  true获取内网地址 false获取外网地址
        if (isInner) {
            m_strSubSystemUrl = m_strSubInnerSystemUrl;
        }
        BasicPlatformResponse<SubSystemsMainServer> objectBasicPlatformResponse = this.basicPlatformGet(m_strSubSystemUrl, hashMap, null);
        if (objectBasicPlatformResponse.getStatusCode().equals(HttpStatus.OK.value())) {
            List<SubSystemsMainServer> dataList = objectBasicPlatformResponse.getDataList(SubSystemsMainServer.class);
            subSystemsMainServer = dataList.stream().findFirst().orElseGet(SubSystemsMainServer::new);
            return subSystemsMainServer;
        }
        return subSystemsMainServer;
    }


    @Override
    public List<TermBasicInfo> getAllTermInfo(String schoolId) {
        //获取历史学年学期信息
        String path = "/BaseApi/SysMgr/Setting/GetHistoryTermInfoList";
        Map<String, String> map = new HashMap<>();
        map.put("schoolID", schoolId);
        BasicPlatformResponse<TermBasicInfo> termResponse = this.basicPlatformGet(path, map, null);
        List<TermBasicInfo> list = termResponse.getDataList(TermBasicInfo.class);
        return list;
    }

    @Override
    public CurrentTermInfo getCurrentTermInfo(String schoolId) {
        //获取当前学年学期信息 http://192.168.129.1:8033/showdoc/web/#/6?page_id=1243
        String path = "/BaseApi/SysMgr/Setting/GetCurrentTermInfo";
        Map<String, String> map = new HashMap<>();
        map.put("schoolID", schoolId);
        BasicPlatformResponse<CurrentTermInfo> termResponse = this.basicPlatformGet(path, map, null);
        CurrentTermInfo currentTermInfo = termResponse.getDataObject(CurrentTermInfo.class);
        return currentTermInfo;
    }

    @Override
    public UserInfo getUserInfoByToken(String token) {
        //http://192.168.129.1:8033/showdoc/web/#/6?page_id=3656
        String path = "/BaseApi/Login/GetOnlineUserInfo";
        Map<String, String> map = new HashMap<>();
        map.put("token", token);
        BasicPlatformResponse<UserInfo> userInfoList = this.basicPlatformGet(path, map, null);
        UserInfo userInfo = userInfoList.getDataObject(UserInfo.class);
        if (userInfo == null || StrUtil.isBlank(userInfo.getUserID())) {
            log.info(userInfoList.toString());
            throw new RuntimeException(userInfoList.getMsg());
        }
        return userInfo;
    }

    @Override
    @Cacheable(cacheNames = "base:userIdeftify", key = "#userId")
    public List<IdentifyType> getIdentityTypeByUserID(String userId, String token) {
        //http://192.168.129.1:8033/showdoc/web/#/6?page_id=1766
        String path = "/UserMgr/PowerMgr/GetIdentityTypeByUserID2?UserID=" + userId;
        Map<String, String> heardMap = new HashMap<>();
        Map<String, String> map = new HashMap<>();
        heardMap.put("Authorization", "X-Token=" + token);
        heardMap.put("UserID", userId);
        BasicPlatformResponse<IdentifyType> identifyTypeList = this.basicPlatformGet(path, map, heardMap);
        List<IdentifyType> dataList = identifyTypeList.getDataList(IdentifyType.class);
        return dataList;
    }

    @Override
    public LockerInfo getSubSystemLockerInfoByID(String schoolId) {
        //.通过加密锁号获取锁控信息 http://192.168.129.1:8033/showdoc/web/#/6?page_id=5393
        String path = "/BaseApi/LockerMgr/GetSubSystemLockerInfoByID";
        Map<String, String> map = new HashMap<>();
        map.put("schoolID", schoolId);
        map.put("lockerID", lancooConfig.getLockerId());
        map.put("requestTime", DateUtil.now());
        map.put("secCode", MD5Util.MD5encryptRevs(lancooConfig.getLockerId() + DateUtil.now()));
        BasicPlatformResponse<LockerInfo> lockInfo = this.basicPlatformGet(path, map, null);
        LockerInfo lockerInfo = lockInfo.getDataObject(LockerInfo.class);
        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("1", "获取成功");
        resultMap.put("-1", "未检测到加密锁");
        resultMap.put("-2", "加密锁已过试用期");
        resultMap.put("-3", "加密锁不能用于该产品");
        resultMap.put("-4", "加密锁接口调用错误");
        resultMap.put("-5", "加密锁时钟错误");
        resultMap.put("-9", "接口调用异常");
        resultMap.put("-10", "输入参数不正确");
        lockerInfo.setResultExplain(resultMap.get(lockerInfo.getResult()));
        return lockerInfo;
    }

    @Override
    public Integer logout(String userId, String token) {
        //http://192.168.129.1:8033/showdoc/web/#/6?page_id=5192
        String path = "/BaseApi/Login/Logout";
        Map map = new HashMap<>();
        map.put("appid", lancooConfig.getSysId());
        map.put("token", token);
        map.put("UserID", userId);
        map.put("DeviceType", 0);
        HttpResponse execute = HttpUtil.createPost(lancooConfig.getBaseAddr() + path).form(map).execute();
        LogoutResponse logoutResponse = JSON.parseObject(execute.body(), LogoutResponse.class);
        return logoutResponse.getData();
    }

    @Override
    public List<Scheme> getBasePlanTeaching(Integer taskId, String schoolId) {
        //获取教学计划列表  http://192.168.129.1:8033/showdoc/web/#/57?page_id=5358
//        String path = "/UniversityEdu/External/GetSchemeList"; C#版本
        String path = "/external/teachingPlan/getSchemeList";
        String body;
        try {
            SubSystemsMainServer e34 = this.getSubSystemsMainServer("E34", true);
            if (StrUtil.isBlank(e34.getWsSvrAddr())) {
                throw new BizException(5, "未安装教务系统");
            }
            String url = e34.getWsSvrAddr().concat(path);
            body = HttpUtil.createGet(url)
                    .form("appid", lancooConfig.getSysId())
                    .form("access_token", MD5Util.MD5encryptRevs(lancooConfig.getSysId()))
                    .form("schoolId", schoolId).execute().body();
        } catch (Exception e) {
            SubSystemsMainServer e34 = this.getSubSystemsMainServer("E34", false);
            if (StrUtil.isBlank(e34.getWsSvrAddr())) {
                throw new BizException(5, "未安装教务系统");
            }
            String url = e34.getWsSvrAddr().concat(path);
            body = HttpUtil.createGet(url)
                    .form("appid", lancooConfig.getSysId())
                    .form("access_token", MD5Util.MD5encryptRevs(lancooConfig.getSysId()))
                    .form("schoolId", schoolId).execute().body();
        }
        JSONObject jsonObject = JSON.parseObject(body);
        Integer error = jsonObject.getInteger("code");
        if (error == 0) {
            List<Scheme> data = jsonObject.getJSONArray("data").toJavaList(Scheme.class);
            return data;
        } else {
            log.error("获取教学计划列表失败，code:" + error);
            return new ArrayList<>();
        }
    }

    @Override
    public List<BuildingInfo> getBaseRoom(String schoolId) {
        //获取楼宇-楼层-课室-设备的融合数据  http://192.168.129.179:8080/web/#/5/48
        String path = "/api/buildingFloorRoomInfo";
        Map map = new HashMap<>();
        map.put("option", 1);
        map.put("schoolId", schoolId);
        try {
            DigitizationResponse<Buildings> buildingInfoResponse = this.digitizationGet(path, map);
            return buildingInfoResponse.getDataObject(Buildings.class).getBuildings();
        } catch (Exception e) {
            throw new RuntimeException("获取教室失败");
        }
    }

    @Override
    public List<BaseCollege> getCollege(String schoolId) {
        //获取学院信息  http://192.168.129.1:8033/showdoc/web/#/6?page_id=969
        String path = "/ScheduleExternal/api/university/getCollegeInfo";
        Map<String, String> map = new HashMap<>();
        map.put("schoolID", schoolId);
        BasicPlatformResponse<BaseCollege> collegeRes = this.basicPlatformGet(path, map, null);
        List<BaseCollege> baseColleges = collegeRes.getDataList(BaseCollege.class);
        return baseColleges;
    }

    @Override
    public List<BaseStudent> getStudent(String schoolId) {
        //获取全部学生 http://192.168.129.1:8033/showdoc/web/#/6?page_id=968
        String path = "/ScheduleExternal/api/university/GetStudentInfo";
        Map<String, String> map = new HashMap<>();
        map.put("schoolID", schoolId);
        BasicPlatformResponse<BaseStudent> baseTeachers = this.basicPlatformGet(path, map, null);
        List<BaseStudent> list = baseTeachers.getDataList(BaseStudent.class);
        return list;
    }

    @Override
    public List<BaseTeacher> getTeacher(String schoolId) {
        //获取教师 http://192.168.129.1:8033/showdoc/web/#/6?page_id=1225
        String path = "/BaseApi/UserMgr/UserInfoMgr/GetTeacher_Univ";
        Map<String, String> map = new HashMap<>();
        map.put("schoolID", schoolId);
        BasicPlatformResponse<BaseTeacher> baseTeachers = this.basicPlatformGet(path, map, null);
        return baseTeachers.getDataList(BaseTeacher.class);
    }

    @Override
    public List<BasePeriodScheme> getPeriodScheme(String schoolId) {
        // http://192.168.129.1:8033/showdoc/web/?#/6?page_id=1321
        String path = "/BaseApi/UserMgr/TeachInfoMgr/GetScheduleHours";
        Map<String, String> map = new HashMap<>();
        map.put("schoolID", schoolId);
        BasicPlatformResponse<BasePeriodScheme> basePeriodScheme = this.basicPlatformGet(path, map, null);
        return basePeriodScheme.getDataList(BasePeriodScheme.class);
    }

    @Override
    public List<BaseCourse> getBaseCourse(String schoolId) {
        //获取课程信息 http://192.168.129.1:8033/showdoc/web/#/57?page_id=5310
        String path = "/External/GetCourseList";
        String body;
        try {
            SubSystemsMainServer e34 = this.getSubSystemsMainServer("E34", true);
            if (StrUtil.isBlank(e34.getWsSvrAddr())) {
                throw new BizException("未安装教务系统");
            }
            String url = e34.getWsSvrAddr().concat(path);
            body = HttpUtil.createGet(url)
                    .form("appid", lancooConfig.getSysId())
                    .form("access_token", MD5Util.MD5encryptRevs(lancooConfig.getSysId()))
                    .form("SchoolID", schoolId).execute().body();
        } catch (Exception e) {
            SubSystemsMainServer e34 = this.getSubSystemsMainServer("E34", false);
            if (StrUtil.isBlank(e34.getWsSvrAddr())) {
                throw new BizException("未安装教务系统");
            }
            String url = e34.getWsSvrAddr().concat(path);
            body = HttpUtil.createGet(url)
                    .form("appid", lancooConfig.getSysId())
                    .form("access_token", MD5Util.MD5encryptRevs(lancooConfig.getSysId()))
                    .form("SchoolID", schoolId).execute().body();
        }
        JSONObject jsonObject = JSON.parseObject(body);
        Integer error = jsonObject.getInteger("code");
        if (error == 0) {
            List<BaseCourse> data = jsonObject.getJSONArray("data").toJavaList(BaseCourse.class);
            return data;
        } else {
            log.error("获取课程列表失败，code为:" + error);
            throw new RuntimeException("获取课程库列表失败");
        }
    }

    @Override
    public List<BaseLink> getBaseSegment(String schoolId) {
        //获取环节信息 http://192.168.129.1:8033/showdoc/web/#/57?page_id=5372
        String path = "/External/GetLinkList";
        String body;
        try {
            SubSystemsMainServer e34 = this.getSubSystemsMainServer("E34", true);
            if (StrUtil.isBlank(e34.getWsSvrAddr())) {
                throw new BizException("未安装教务系统");
            }
            String url = e34.getWsSvrAddr().concat(path);
            body = HttpUtil.createGet(url)
                    .form("appid", lancooConfig.getSysId())
                    .form("access_token", MD5Util.MD5encryptRevs(lancooConfig.getSysId()))
                    .form("SchoolID", schoolId).execute().body();
        } catch (Exception e) {
            SubSystemsMainServer e34 = this.getSubSystemsMainServer("E34", false);
            if (StrUtil.isBlank(e34.getWsSvrAddr())) {
                throw new BizException("未安装教务系统");
            }
            String url = e34.getWsSvrAddr().concat(path);
            body = HttpUtil.createGet(url)
                    .form("appid", lancooConfig.getSysId())
                    .form("access_token", MD5Util.MD5encryptRevs(lancooConfig.getSysId()))
                    .form("SchoolID", schoolId).execute().body();
        }
        JSONObject jsonObject = JSON.parseObject(body);
        Integer error = jsonObject.getInteger("code");
        if (error == 0) {
            List<BaseLink> data = jsonObject.getJSONArray("data").toJavaList(BaseLink.class);
            return data;
        } else {
            log.error("获取环节列表失败，code为:" + error);
            throw new RuntimeException("获取环节库列表失败");
        }
    }

    /**
     * 基础平台接口调用封装
     *
     * @param path
     * @param map
     * @param <T>
     * @return
     */
    public <T> BasicPlatformResponse<T> basicPlatformGet(String path, Map map, Map heardMap) {
        //系统id
        String strAppId = lancooConfig.getSysId();
        String Md5_AppId = DigestUtils.md5DigestAsHex(strAppId.getBytes());
        StringBuilder sb = new StringBuilder(Md5_AppId);
        String strAccess_token = sb.reverse().toString();

        String url = lancooConfig.getBaseAddr().concat(path);
        try {
            HttpRequest get = HttpUtil.createGet(url);
            map.put("appid", strAppId);
            map.put("access_token", strAccess_token);
            get.form(map);
            get.addHeaders(heardMap);
            HttpResponse execute = get.execute();
//            log.info(execute.body());
            return JSONObject.parseObject(execute.body(), BasicPlatformResponse.class);
        } catch (Exception e) {
            log.error("请求基础平台失败", e);
            throw new RuntimeException("请求基础平台失败" + e);
        }
//        return new BasicPlatformResponse<>();
    }

    /**
     * 基础信息获取（数字化档案管理）
     *
     * @param path
     * @param map
     * @return
     */
    public <T> DigitizationResponse<T> digitizationGet(String path, Map map) {
        //系统id
        String strAppId = lancooConfig.getSysId();
        String Md5_AppId = DigestUtils.md5DigestAsHex(strAppId.getBytes());
        StringBuffer sb = new StringBuffer(Md5_AppId);
        String strAccess_token = sb.reverse().toString();

        Map<String, String> header = new HashMap<>();
        header.put("sysid", strAppId);
        header.put("Authorization", strAccess_token);
        String body;
        try {
            SubSystemsMainServer e01 = this.getSubSystemsMainServer("E01", true);
            if (StrUtil.isBlank(e01.getWebSvrAddr())) {
                throw new BizException(5, "不存在数字化系统");
            }
            String url = e01.getWsSvrAddr().concat(path);
            body = HttpUtil.createGet(url)
                    .addHeaders(header)
                    .form(map).execute().body();
            return JSONObject.parseObject(body, DigitizationResponse.class);
        } catch (Exception e) {
            SubSystemsMainServer e01 = this.getSubSystemsMainServer("E01", false);
            if (StrUtil.isBlank(e01.getWebSvrAddr())) {
                throw new BizException(5, "不存在数字化系统");
            }
            String url = e01.getWsSvrAddr().concat(path);
            try {
                body = HttpUtil.createGet(url)
                        .addHeaders(header)
                        .form(map).execute().body();
                return JSONObject.parseObject(body, DigitizationResponse.class);
            } catch (Exception ex) {
                log.error("请求数字化档案管理失败", ex);
            }
        }
        return new DigitizationResponse<>();
    }

    @Override
    @Async("asyncExecutor")
    public void uploadLog(String schoolId, String userId, String userName, String operationTerminal, String operationType, String operationContent, String taskId) {
        String e80 = this.getSubSystemsMainServer("E80", false).getWsSvrAddr();
        if (StrUtil.isBlank(e80)) {
            return;
        }
        MessageBody<EducationLog> body = new MessageBody<>("X00", "894_ADD_LOG", EducationLog.builder()
                .sysId(lancooConfig.getSysId())
                .sysName("智能排课选课")
                .modelId(lancooConfig.getSysId() + "001")
                .modelName("智能排课选课")
                .userId(userId)
                .userName(userName)
                .schoolId(schoolId)
                .operationTime(DateUtil.now())
                .operationTerminal(operationTerminal)
                .operationType(operationType)
                .operationContent(operationContent)
                .remark(taskId)
                .build());
        HttpUtil.post(e80 + "/sendMsg", JSONObject.toJSONString(body));
        log.info("sendMessage operationContent : {}", operationContent);
    }

    @Override
    @Async("asyncExecutor")
    public void sendOpenCoursePlanApplyMsg(LocalDateTime setBeginTime, LocalDateTime setEndTime, Integer taskId, String userId, String userName) {
        TaskInfo taskInfo = taskInfoService.getById(taskId);
        List<NewMessage.UserInfo> sendList = new ArrayList<>();
        this.getCollege(taskInfo.getSchoolId()).stream()
                .filter(baseCollege -> ObjUtil.isNotEmpty(baseCollege.getAdmins()))
                .flatMap(baseCollege -> baseCollege.getAdmins().stream())
                .collect(Collectors.toList()).forEach(user ->
                sendList.add(NewMessage.UserInfo.builder().userId(user.getUserID()).userName(user.getUserName()).userType(0).build()));

        //【{XX学年第一学期}】开课计划已经可以申请啦，开放时段【{{2022-11-28 10:00}}】到【{2022-12-03 10:00}】，请及时进行确认~
        String content = taskInfo.getTermName() + "%@%" + setBeginTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + "%@%" + setEndTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        NewMessage message = NewMessage.getMessageTemple()
                .setEventId("E310201")
                .setTemplateId("E3114")
                .setTemplateParam(content)
                .setUserId(userId)
                .setUserName(userName)
                .setUserType(0)
                .setSchoolId(taskInfo.getSchoolId())
                .setSendObject(sendList);
        log.info("sendOpenCoursePlanApplyMsg -- content : {} ", content);
        this.sendMsg(message);
    }

    @Override
    @Async("asyncExecutor")
    public void sendOpenTeachTaskApplyMsg(LocalDateTime setBeginTime, LocalDateTime setEndTime, Integer taskId, String userId, String userName) {
        TaskInfo taskInfo = taskInfoService.getById(taskId);
        List<NewMessage.UserInfo> sendList = new ArrayList<>();
        this.getCollege(taskInfo.getSchoolId()).stream()
                .filter(baseCollege -> ObjUtil.isNotEmpty(baseCollege.getAdmins()))
                .flatMap(baseCollege -> baseCollege.getAdmins().stream())
                .collect(Collectors.toList()).forEach(user ->
                sendList.add(NewMessage.UserInfo.builder().userId(user.getUserID()).userName(user.getUserName()).userType(0).build()));

        //【{XX学年第一学期}】教学任务已经可以开发处理啦，开放时段【{{2022-11-28 10:00}}】到【{2022-12-03 10:00}】，请及时进行确认~
        String content = taskInfo.getTermName() + "%@%" + setBeginTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + "%@%" + setEndTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        NewMessage message = NewMessage.getMessageTemple()
                .setEventId("E310202")
                .setTemplateId("E3115")
                .setTemplateParam(content)
                .setUserId(userId)
                .setUserName(userName)
                .setUserType(0)
                .setSchoolId(taskInfo.getSchoolId())
                .setSendObject(sendList);
        log.info("sendOpenTeachTaskApplyMsg -- content : {} ", content);
        this.sendMsg(message);
    }

    @Override
    @Async("asyncExecutor")
    public void sendSelectCourseStartMsg(LocalDateTime setBeginTime, LocalDateTime setEndTime, Integer taskId, String module, String userId, String userName, String authorization) {
        TaskInfo taskInfo = taskInfoService.getById(taskId);
        NoticeBody.ReceiverDTO receiverDTO = NoticeBody.ReceiverDTO.builder()
                .identities(ListUtil.toList(NoticeBody.ReceiverDTO.IdentitiesDTO.builder()
                        .identityCode("IC0014")
                        .identityName("学生")
                        .build()))
                .build();

        //【{XX学年第一学期}】【{预选/正选/补选/退选}】将在【{2022-11-28 10:00}】开启，并于【{2022-12-03 10:00}】结束，请在选课时间内完成选课~
        String content = "【{}】【{}】将在【{}】开启，并于【{}】结束，请在选课时间内完成选课~";
        try {
            NoticeBody noticeBody = NoticeBody.getStudentNoticeTemple()
                    .setTitle("选课通知")
                    .setContent(StrUtil.format(content, taskInfo.getTermName(), module, setBeginTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), setEndTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))))
                    .setUserId(userId)
                    .setUserName(URLDecoder.decode(userName, "utf-8"))
                    .setStartTime(setBeginTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                    .setEndTime(setEndTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                    .setSchoolId(taskInfo.getSchoolId())
                    .setReceiver(receiverDTO);
            this.sendNotice(noticeBody, authorization);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    @Override
    @Async("asyncExecutor")
    public void sendSelectCourseEndMsg(LocalDateTime setEndTime, Integer taskId, String module, Integer roundId) {
        // 定时器每天凌晨1点遍历css_task_round表，获取结束时间刚好在今天的记录，然后获取其选课信息，发送消息
        TaskInfo taskInfo = taskInfoService.getById(taskId);

        List<NewMessage.UserInfo> sendList = new ArrayList<>();
        if (roundId != null) {
            // 获取轮次下的学生
            List<CssStudentRange> cssRanges = cssStudentRangeService.lambdaQuery().eq(CssStudentRange::getRoundId, roundId).list();
            List<String> collegeIds = cssRanges.stream().map(CssStudentRange::getBaseCollegeId).collect(Collectors.toList());
            if (collegeIds.size() > 0) {
                studentService.lambdaQuery().eq(Student::getTaskId, taskId).in(Student::getBaseCollegeId, collegeIds).list().forEach(student ->
                        sendList.add(NewMessage.UserInfo.builder().userId(student.getBaseStudentId()).userName(student.getStudentName()).userType(2).build()));
            }
            List<String> gradeIds = cssRanges.stream().map(CssStudentRange::getGradeId).collect(Collectors.toList());
            if (gradeIds.size() > 0) {
                studentService.lambdaQuery().eq(Student::getTaskId, taskId).in(Student::getGradeId, gradeIds).list().forEach(student ->
                        sendList.add(NewMessage.UserInfo.builder().userId(student.getBaseStudentId()).userName(student.getStudentName()).userType(2).build()));
            }
        } else {
            // 获取任务下的学生
            studentService.lambdaQuery().eq(Student::getTaskId, taskId).list().forEach(student ->
                    sendList.add(NewMessage.UserInfo.builder().userId(student.getBaseStudentId()).userName(student.getStudentName()).userType(2).build()));
        }
        //【{XX学年第一学期}】【{预选/正选/补选/退选}】将在【{2022-12-03 10:00}】结束，请确认您的课程是否已经选上~
        String content = taskInfo.getTermName() + "%@%" + module + "%@%" + setEndTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        NewMessage message = NewMessage.getMessageTemple()
                .setEventId("E310204")
                .setTemplateId("E3117")
                .setTemplateParam(content)
                .setUserId(lancooConfig.getSysId())
                .setUserName("智能排课选课")
                .setUserType(-1)
                .setSchoolId(taskInfo.getSchoolId())
                .setSendObject(sendList.stream().distinct().collect(Collectors.toList()));
        log.info("sendSelectCourseEndMsg -- content : {} ", content);
        this.sendMsg(message);
    }

    @Override
    public HttpResponse sendSelectCourseEndMsg(Integer taskId, String roundName, String userId, String userName) {
        TaskInfo taskInfo = taskInfoService.getById(taskId);
        NoticeBody.ReceiverDTO receiverDTO = NoticeBody.ReceiverDTO.builder()
                .identities(ListUtil.toList(NoticeBody.ReceiverDTO.IdentitiesDTO.builder()
                        .identityCode("IC0014")
                        .identityName("学生")
                        .build()))
                .build();

        //        <p> <a href=\"https://xdtest.aiedu100.com/notice/web/html/announcement/index.html?lg_tk=c798a8076974415f9f3279973176d8ea&lg_ic=IC0001&noticeId=1919640554635874306&taskReleaseId=#/noticeDetail\" target=\"_blank\">点击查看</a> </p>
//        SubSystemsMainServer subSystemsMainServer = this.getSubSystemsMainServer("E31", false);
//        String ip = StrUtil.isNotBlank(subSystemsMainServer.getWebSvrAddr()) ? subSystemsMainServer.getWebSvrAddr() : lancooConfig.getBaseAddr();
//        String content = "<a href='{}?#/studentHome' target='_blank'>【{} {}】选课已结束~</a>";

        String content = "【{} {}】选课已结束~";
        NoticeBody noticeBody = NoticeBody.getStudentNoticeTemple()
                .setTitle("选课结束通知")
                .setContent(StrUtil.format(content, taskInfo.getTermName(),roundName))
                .setUserId(userId)
                .setUserName(userName)
                .setSchoolId(taskInfo.getSchoolId())
                .setReceiver(receiverDTO);
        return this.sendNoticeNoToken(noticeBody);
    }

    private void sendMsg(NewMessage message) {
        SubSystemsMainServer subSystemsMainServer = this.getSubSystemsMainServer("210", true);
        if (StrUtil.isBlank(subSystemsMainServer.getWsSvrAddr())) {
            return;
        }
        //新版消息系统地址
        String path = "/api/foreign/message/create";
        String targetPath = subSystemsMainServer.getWsSvrAddr() + path;
        try {
            HttpUtil.post(targetPath, JSONObject.toJSONString(message));
        } catch (Exception e) {
            log.error(e.toString());
        }
        // eventId templateId templateParam userId  userName userType  schoolId sendObject
        //user_type 3 家长 2学生 0院系管理员
    }

    @Override
    @Cacheable(cacheNames = "base:userInfo", key = "#userId")
    public UserInfo getUserInfo(String userId) {
        //搜索用户 http://192.168.129.1:8033/showdoc/web/?#/6?page_id=1562
        String path = "/BaseApi/UserMgr/UserInfoMgr/SearchUserByIDsOrName";
        Map<String, String> map = new HashMap<>();
        map.put("userIDs", userId);
        BasicPlatformResponse<UserInfo> userInfoList = this.basicPlatformGet(path, map, null);
        List<UserInfo> list = userInfoList.getDataList(UserInfo.class);
        if (CollUtil.isEmpty(list)) {
            throw new RuntimeException("不存在该用户");
        }
        return list.get(0);
    }

    @Override
    public ResponseObject syncAllScheduleToBasic(Integer taskId, String userId, String userName, String schoolId, Integer type) {
        RLock lock = redissonClient.getLock(GlobalConstant.REDIS_PREFIX + taskId + ":" + "syncAllScheduleToBasic");
        lock.lock(600, TimeUnit.SECONDS);
        //同步教学班前先同步教学班
        try {
            SplitTeacherTeachingClass.clear();
            ResponseObject responseObject = this.syncTeachingClassToBasic(taskId, userId, userName, schoolId, CommonConstants.COVER, type);
            //上传教学班成功后上传课表
            if (responseObject.getErrCode() == 0) {
                return syncScheduleToBasic(taskId, userId, userName, schoolId, type);
            } else {
                return responseObject;
            }
        } catch (Exception e) {
            log.error("同步课表失败", e);
        } finally {
            lock.unlock();
        }
        return ResponseObject.ofFail("上传课表失败");
    }


    @Override
//    @Async("asyncExecutor")
    public List<Retake> syncRetakeStudent(Integer taskId, String schoolId, String term) {
        //获取重修学生 https://www.showdoc.com.cn/2192008349869568/10006026408195290
        String path = "PBRetake/GetRetakeList";

        HttpResponse execute;
        try {
            SubSystemsMainServer subSystemsMainServer = this.getSubSystemsMainServer("812", false);
            if (StrUtil.isBlank(subSystemsMainServer.getWsSvrAddr())) {
                log.warn("未安装成绩管理系统");
                return null;
            }
            String url = subSystemsMainServer.getWsSvrAddr().concat(path);

            Map<String, Object> map = new HashMap<>();
            HttpRequest get = HttpUtil.createGet(url);
            map.put("appid", lancooConfig.getSysId());
            map.put("access_token", MD5Util.MD5encryptRevs(lancooConfig.getSysId()));
            map.put("SchoolID", schoolId);
            map.put("Term", term);
            get.form(map);
            //请求头参数
            get.addHeaders(null);
            execute = get.execute();


        } catch (Exception e) {

            SubSystemsMainServer subSystemsMainServer = this.getSubSystemsMainServer("812", true);
            if (StrUtil.isBlank(subSystemsMainServer.getWsSvrAddr())) {
                log.warn("未安装成绩管理系统");
                return null;
            }
            String url = subSystemsMainServer.getWsSvrAddr().concat(path);

            Map<String, Object> map = new HashMap<>();
            HttpRequest get = HttpUtil.createGet(url);
            map.put("appid", lancooConfig.getSysId());
            map.put("access_token", MD5Util.MD5encryptRevs(lancooConfig.getSysId()));
            map.put("SchoolID", schoolId);
            map.put("Term", term);
            map.put("CourseSort", 0);
            get.form(map);
            //请求头参数
            get.addHeaders(null);
            execute = get.execute();
        }

        BasicPlatformResponse<Retake> scoreResponse = JSONObject.parseObject(execute.body(), BasicPlatformResponse.class);
        return scoreResponse.getDataList(Retake.class);
    }

    @Override
    @Async("asyncExecutor")
    public void sendSelectCourseCancelMsg(List<Long> teachingClassIds, Integer taskId, String userId, String userName, String authorization) {
        TaskInfo taskInfo = taskInfoService.getById(taskId);
        List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery().in(TeachingClass::getTeachingClassId, teachingClassIds).list();
        if (CollUtil.isNotEmpty(teachingClassList)) {
            //判断教学班是否是在线选课
            if (teachingClassList.get(0).getTeachingClassType().equals(1)) {
                teachingClassList.forEach(teachingClass -> {
                    List<NoticeBody.ReceiverDTO.PersonsDTO> sendList = new ArrayList<>();
                    Page<Student> page = new Page<>(1, -1);
                    studentService.getStudentsByTeachingClassId(page, teachingClass.getTeachingClassId(), null, null, null, null, taskId).getList()
                            .forEach(student -> {
                                sendList.add(NoticeBody.ReceiverDTO.PersonsDTO.builder().userId(student.getBaseStudentId()).userName(student.getStudentName()).photoPath(student.getImageUrl()).build());
                            });
                    //您的选课课程【{公共关系与礼仪}】，因为开班人数不足，已被管理员取消，请知悉~
                    try {
                        NoticeBody noticeBody = NoticeBody.getStudentNoticeTemple()
                                .setTitle("选课通知")
                                .setContent(StrUtil.format("您的选课课程【{}】，因为开班人数不足，已被管理员取消，请知悉~", teachingClass.getTeachingClassName()))
                                .setUserId(userId)
                                .setUserName(URLDecoder.decode(userName, "utf-8"))
                                .setStartTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                                .setEndTime(LocalDateTime.now().plusWeeks(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                                .setSchoolId(taskInfo.getSchoolId())
                                .setReceiver(NoticeBody.ReceiverDTO.builder().persons(sendList).build());
                        this.sendNotice(noticeBody, authorization);
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                });
            }
        }
    }

    @Override
    @Async("asyncExecutor")
    public void sendCoursePlanExamineMsg(Integer taskId) {
        // 定时器每天凌晨1点获取开课计划时间，获取结束时间刚好在今天的记录，发送信息
        TaskInfo taskInfo = taskInfoService.getById(taskId);

        List<NewMessage.UserInfo> sendList = new ArrayList<>();
        //获取教务管理员
        List<UserInfoMsg> ic0002 = this.getUserInfoMsg(taskInfo.getSchoolId(), "IC0002");
        ic0002.forEach(userInfoMsg -> {
            sendList.add(NewMessage.UserInfo.builder().userId(userInfoMsg.getUserID()).userName(userInfoMsg.getUserName()).userType(0).build());
        });

        //请注意：开课计划变更申请已截止，请及时前往审核~
        String content = "template";
        NewMessage message = NewMessage.getMessageTemple()
                .setEventId("E310206")
                .setTemplateId("E3119")
                .setTemplateParam(content)
                .setUserId(lancooConfig.getSysId())
                .setUserName("智能排课选课")
                .setUserType(-1)
                .setSchoolId(taskInfo.getSchoolId())
                .setSendObject(sendList);
        log.info("sendSelectCourseEndMsg -- content : {}", content);
        this.sendMsg(message);
    }

    @Override
    @Async("asyncExecutor")
    public void sendCoursePlanExamineResultMsg(MsgCoursePlanExamine msgCoursePlanExamine) {
        TaskInfo taskInfo = taskInfoService.getById(msgCoursePlanExamine.getTaskId());
        List<NewMessage.UserInfo> sendList = new ArrayList<>();
        sendList.add(NewMessage.UserInfo.builder().userId(msgCoursePlanExamine.getSendUserId()).userName(msgCoursePlanExamine.getSendUserName()).userType(0).build());

        //您的开课计划变更【{课程名/环节名}】{已通过审核/已驳回}，请知悉~
        String content = msgCoursePlanExamine.getCourseName() + "%@%" + (msgCoursePlanExamine.getExamine() == 1 ? "已通过审核" : "已驳回");
        NewMessage message = NewMessage.getMessageTemple()
                .setEventId("E310207")
                .setTemplateId("E3120")
                .setTemplateParam(content)
                .setUserId(msgCoursePlanExamine.getUserId())
                .setUserName(msgCoursePlanExamine.getUserName())
                .setUserType(0)
                .setSchoolId(taskInfo.getSchoolId())
                .setSendObject(sendList);
        log.info("sendCoursePlanExamineResultMsg -- content : {} ", content);
        this.sendMsg(message);
    }

    @Override
    @Async("asyncExecutor")
    public void sendTimeAdjustmentMsg(MsgTimeAdjustment msgTimeAdjustment) {
        TaskInfo taskInfo = taskInfoService.getById(msgTimeAdjustment.getTaskId());

        List<NewMessage.UserInfo> sendList = new ArrayList<>();
        this.getCollege(taskInfo.getSchoolId()).stream()
                .filter(baseCollege -> ObjUtil.isNotEmpty(baseCollege.getAdmins()))
                .flatMap(baseCollege -> baseCollege.getAdmins().stream())
                .collect(Collectors.toList()).forEach(user ->
                sendList.add(NewMessage.UserInfo.builder().userId(user.getUserID()).userName(user.getUserName()).userType(0).build()));

        //【{XX学年第一学期}】【{开课计划/预选课程/教学任务}】处理时段，已调整为【{2023-08-09 10:00}】到【{2023-08-11 10:00}】，请知悉~
        String content = taskInfo.getTermName() + "%@%" + msgTimeAdjustment.getModuleName()
                + "%@%" + msgTimeAdjustment.getSetBeginTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
                + "%@%" + msgTimeAdjustment.getSetEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        NewMessage message = NewMessage.getMessageTemple()
                .setEventId("E310208")
                .setTemplateId("E3121")
                .setTemplateParam(content)
                .setUserId(msgTimeAdjustment.getUserId())
                .setUserName(msgTimeAdjustment.getUserName())
                .setUserType(0)
                .setSchoolId(taskInfo.getSchoolId())
                .setSendObject(sendList);
        log.info("sendCoursePlanExamineResultMsg -- content : {} ", content);
        this.sendMsg(message);
    }

    @Override
    @Async("asyncExecutor")
    public void sendTimeAdjustmentEndMsg(MsgTimeAdjustment msgTimeAdjustment) {
        TaskInfo taskInfo = taskInfoService.getById(msgTimeAdjustment.getTaskId());
        List<NewMessage.UserInfo> sendList = new ArrayList<>();
        this.getCollege(taskInfo.getSchoolId()).stream()
                .filter(baseCollege -> ObjUtil.isNotEmpty(baseCollege.getAdmins()))
                .flatMap(baseCollege -> baseCollege.getAdmins().stream())
                .collect(Collectors.toList()).forEach(user ->
                sendList.add(NewMessage.UserInfo.builder().userId(user.getUserID()).userName(user.getUserName()).userType(0).build()));

        //【{XX学年第一学期}】【{开课计划/预选课程/教学任务}】处理时段已结束，请知悉~
        String content = taskInfo.getTermName() + "%@%" + msgTimeAdjustment.getModuleName();
        NewMessage message = NewMessage.getMessageTemple()
                .setEventId("E310209")
                .setTemplateId("E3122")
                .setTemplateParam(content)
                .setUserId(msgTimeAdjustment.getUserId())
                .setUserName(msgTimeAdjustment.getUserName())
                .setUserType(0)
                .setSchoolId(taskInfo.getSchoolId())
                .setSendObject(sendList);
        log.info("sendCoursePlanExamineResultMsg -- content : {} ", content);
        this.sendMsg(message);
    }

    public List<UserInfoMsg> getUserInfoMsg(String schoolId, String IdentityCode) {
        //获取管理员  http://192.168.129.1:8033/showdoc/web/?#/6?page_id=1209
        String path = "/BaseApi/UserMgr/UserInfoMgr/GetAdmin_Univ";

        HashMap<String, String> map = new HashMap<>();
        map.put("schoolID", schoolId);
        map.put("IdentityCode", IdentityCode);
        BasicPlatformResponse<UserInfoMsg> userInfoList = this.basicPlatformGet(path, map, null);
        List<UserInfoMsg> userInfoMsgList = userInfoList.getDataList(UserInfoMsg.class);
        return userInfoMsgList;
    }

    private void sendNotice(NoticeBody noticeBody, String authorization) {
        SubSystemsMainServer subSystemsMainServer = this.getSubSystemsMainServer("220", false);
        if (StrUtil.isBlank(subSystemsMainServer.getWsSvrAddr())) {
            return;
        }
        //http://192.168.129.165/web/#/40/666
        String path = "/api/notice/created/release";
        String targetPath = subSystemsMainServer.getWsSvrAddr() + path;
        try {
            HttpRequest.post(targetPath)
                    .header("Authorization", authorization)
                    .body(JSONObject.toJSONString(noticeBody))
                    .execute();
            log.info("发送学校通知：{}", JSONObject.toJSONString(noticeBody));
        } catch (Exception e) {
            log.error(e.toString());
        }

    }

    private HttpResponse sendNoticeNoToken(NoticeBody noticeBody) {
        SubSystemsMainServer subSystemsMainServer = this.getSubSystemsMainServer("220", false);
        if (StrUtil.isBlank(subSystemsMainServer.getWsSvrAddr())) {
            return null;
        }
        //http://192.168.129.165/web/#/40/666
        String path = "/api/notice/foreign/release";
        String targetPath = subSystemsMainServer.getWsSvrAddr() + path;
        try {
            HttpResponse httpResponse = HttpRequest.post(targetPath)
                    .body(JSONObject.toJSONString(noticeBody))
                    .execute();
            log.info("发送学校通知：{}", JSONObject.toJSONString(noticeBody));
            return httpResponse;
        } catch (Exception e) {
            log.error(e.toString());
        }
        return null;
    }

    private ResponseObject syncScheduleToBasic(Integer taskId, String userId, String userName, String schoolId, Integer type) {
        //大学版排课同步课表信息
        String path = "/ScheduleExternal/api/university/ImportSchedule";
        try {
            String scheduleInfoPath = this.getSubSystemsMainServer("E31", true).getWsSvrAddr() + scheduleService.allScheduleToExcel(taskId, type);
            ResponseObject<Object> scheduleResponse = syncRequest(path, scheduleInfoPath, userId, userName, schoolId, "schedule");
            return checkImportProcess(scheduleResponse, "schedule");
        } catch (Exception e) {
            log.error("同步课表失败", e);
        }
        return ResponseObject.ofFail("上传课表失败");
    }


    public ResponseObject syncTeachingClassToBasic(Integer taskId, String userId, String userName, String schoolId, String importMode, Integer type) {
        //大学版排课同步教学班信息
        String path = "/ScheduleExternal/api/university/ImportCourseClass";
        try {
            String e31 = this.getSubSystemsMainServer("E31", false).getWsSvrAddr();
            String classInfoPath = e31 + teachingClassService.allTeachingClassToExcel(taskId, importMode, type);
            ResponseObject<Object> classResponse = syncRequest(path, classInfoPath, userId, userName, schoolId, "class");
            return checkImportProcess(classResponse, "class");
        } catch (Exception e) {
            log.error("同步教学班失败", e);
        }
        return ResponseObject.ofFail("上传教学班失败");
    }

    private ResponseObject checkImportProcess(ResponseObject<Object> responseObject, String type) throws InterruptedException {
        Integer errCode = null;
        if (responseObject.getErrCode() == 0) {
            //http://192.168.129.1:8033/showdoc/web/#/6?page_id=1223 基础平台数据对接进度查询接口
            String checkPath = "/ScheduleExternal/api/CheckImportProcess";
            BasicPlatformResponse responseBasic;
            do {
                Thread.sleep(2000);
                responseBasic = this.basicPlatformGet(checkPath, new HashMap<>(), new HashMap());
                errCode = responseBasic.getErrCode();
            } while (errCode.equals(0));
            String typeName = "class".equals(type) ? "教学班" : "课表";

            if (errCode.equals(-1)) {
                return ResponseObject.ofFail(-1, StrUtil.format("上传{}部分失败", typeName), responseBasic.getData());
            } else if (errCode.equals(-2)) {
                return ResponseObject.ofFail(-2, StrUtil.format("上传{}全部失败", typeName), responseBasic.getData());
            }
        }
        return responseObject;
    }

    private ResponseObject syncRequest(String path, String targetPath, String userId, String userName, String schoolId, String type) {
        //系统id
        String strAppId = lancooConfig.getSysId();
        String Md5_AppId = DigestUtils.md5DigestAsHex(strAppId.getBytes());
        StringBuilder sb = new StringBuilder(Md5_AppId);
        String strAccess_token = sb.reverse().toString();

        //body参数
        ImportClassInfoRequest importClassInfoRequest = ImportClassInfoRequest.builder()
                .appid(strAppId).access_token(strAccess_token)
                .schoolID(schoolId)
                .userID(userId).userName(userName).build();
        switch (type) {
            case "class":
                importClassInfoRequest.setClassInfoPath(targetPath);
                break;
            case "schedule":
                importClassInfoRequest.setScheduleInfoPath(targetPath);
                break;
            default:
                break;
        }
        String response = HttpUtil.createPost(lancooConfig.getBaseAddr().concat(path))
                .body(JSON.toJSONString(importClassInfoRequest))
                .execute().body();
        JSONObject responseJson = JSON.parseObject(response);
        int statusCode = responseJson.getInteger("StatusCode");
        String msg = responseJson.getString("Msg");
        log.info("=======" + JSON.toJSONString(importClassInfoRequest));
        if (statusCode == 200) {
            return ResponseObject.ofSuccess();
        } else {
            return ResponseObject.ofFail(statusCode, "基础平台接口返回：" + msg, responseJson.getJSONObject("Data"));
        }
    }

    @Override
    public List<BaseGrade> getGrade(String schoolId) {
        //获取年级  http://192.168.129.1:8033/showdoc/web/#/6?page_id=1210
        String path = "/BaseApi/UserMgr/UserInfoMgr/GetGrade_Univ";
        Map<String, String> map = new HashMap<>();
        map.put("schoolID", schoolId);
        BasicPlatformResponse<BaseGrade> gradeResponse = this.basicPlatformGet(path, map, null);
        List<BaseGrade> gradeList = gradeResponse.getDataList(BaseGrade.class);
        return gradeList;
    }
}
